#include "BossPlanets.h"
#include "../SGD Wrappers/SGD_GraphicsManager.h"
#include "GamePlayState.h"
#include "Zone.h"
#include "Player.h"
#include "Game.h"
#include "ParticleManager.h"
#include "../SGD Wrappers/SGD_EventManager.h"
#include "../SGD Wrappers/SGD_Event.h"

/*WeakPoint Methods*/
WeakPoint::WeakPoint(Planets*owner)
{
	eye = SGD::GraphicsManager::GetInstance()->LoadTexture("resources/images/boss/Boss Planet_Lteye.png");
	armor = SGD::GraphicsManager::GetInstance()->LoadTexture("resources/images/boss/Boss Planet_Lteyearmor.png");
	spike = SGD::GraphicsManager::GetInstance()->LoadTexture("resources/images/boss/horn.png");
	broken = SGD::GraphicsManager::GetInstance()->LoadTexture("resources/images/boss/Boss Planet_stone.png");
	currPlanet = owner;
}

WeakPoint::~WeakPoint()
{
	SGD::GraphicsManager::GetInstance()->UnloadTexture(eye);
	SGD::GraphicsManager::GetInstance()->UnloadTexture(armor);
	SGD::GraphicsManager::GetInstance()->UnloadTexture(spike);
	SGD::GraphicsManager::GetInstance()->UnloadTexture(broken);
}

void WeakPoint::Render()
{
	SGD::GraphicsManager* graphics = SGD::GraphicsManager::GetInstance();



	if (!damaged)
	{
		graphics->DrawTextureSection(eye, SGD::Point{ (position.x - Game::GetInstance()->GetCameraPos().x)*Game::GetInstance()->GetZoomLevel(),
			(position.y - Game::GetInstance()->GetCameraPos().y)*Game::GetInstance()->GetZoomLevel() }, { 71, 79, 124, 139 }, 0.0f, {}, {},
			{ Game::GetInstance()->GetZoomLevel(), Game::GetInstance()->GetZoomLevel() });
	}
	else
	{
		graphics->DrawTextureSection(eye, SGD::Point{ (position.x - Game::GetInstance()->GetCameraPos().x)*Game::GetInstance()->GetZoomLevel(),
			(position.y - Game::GetInstance()->GetCameraPos().y)*Game::GetInstance()->GetZoomLevel() }, { 71, 79, 124, 139 }, 0.0f, {}, { 100, 100, 100 },
			{ Game::GetInstance()->GetZoomLevel(), Game::GetInstance()->GetZoomLevel() });
	}

	/*DEBUG RENDERING*/
	if (armored)
	{
		graphics->DrawTextureSection(armor, SGD::Point{ (position.x - Game::GetInstance()->GetCameraPos().x)*Game::GetInstance()->GetZoomLevel(),
			(position.y - Game::GetInstance()->GetCameraPos().y)*Game::GetInstance()->GetZoomLevel() }, { 74, 79, 114, 139 }, 0.0f, {}, {},
			{ Game::GetInstance()->GetZoomLevel(), Game::GetInstance()->GetZoomLevel() });
	}
	if (spiked)
	{
		graphics->DrawTextureSection(spike, SGD::Point{ (position.x - Game::GetInstance()->GetCameraPos().x)*Game::GetInstance()->GetZoomLevel(),
			(position.y - Game::GetInstance()->GetCameraPos().y)*Game::GetInstance()->GetZoomLevel() }, { 110, 79, 140, 105 }, rotation, {}, {},
			{ Game::GetInstance()->GetZoomLevel(), Game::GetInstance()->GetZoomLevel() });
	}
	/*if (tentacles)
		SGD::GraphicsManager::GetInstance()->DrawRectangle(rect, { 255, 255, 0 });
	if (mancerSpawn)
		SGD::GraphicsManager::GetInstance()->DrawRectangle(rect, { 0, 255, 255 });*/
	/*END DEBUG RENDERING*/
}

void WeakPoint::Update(float elapsedTime)
{
	SGD::Rectangle camOffset{ { Game::GetInstance()->GetCameraPos().x - 100,
		Game::GetInstance()->GetCameraPos().y - 100 },
		SGD::Size{ (Game::GetInstance()->GetScreenWidth() + 500) / Game::GetInstance()->GetZoomLevel(),
		(Game::GetInstance()->GetScreenHeight() + 500) / Game::GetInstance()->GetZoomLevel() } };
	SGD::Rectangle posRect = { this->GetRect().ComputeCenter(), SGD::Size{ 1, 1 } };
	if (camOffset.IsIntersecting(posRect))
		collisionFlag = 0;
	else
		collisionFlag = -1;
}

void WeakPoint::HandleCollision(const IEntity* other)
{
	if (other->GetType() == ENT_PLAYER)
	{
		const Player* o = dynamic_cast<const Player*>(other);
		SGD::Vector vel = o->GetVelocity();
		float speed = vel.ComputeLength();
		if (speed > 200 && o->GetCurrentPlanet() == nullptr)
		{
			if (spiked)
			{
				
				SGD::Vector PlayertoSpike = this->GetRect().ComputeCenter() - o->GetRect().ComputeCenter();
				SGD::Vector PlayertoPlanet = o->GetVelocity();
				float angle = PlayertoPlanet.ComputeAngle(PlayertoSpike);
				//float angle = acos(PlayertoSpike.y / PlayertoSpike.ComputeLength());
					if (angle >= .5236f)
					{
						Player * player = const_cast<Player *>(o);
						player->SetHealth(player->GetHealth() - speed / player->GetMass());
						ParticleManager::GetInstance()->CreateEmitter("Blood", player);
						SGD::Event e = { "PLAYERHURT" };
						e.SendEventNow(nullptr);
					}
					else if( angle < .5236f)
					{
						spiked = false;
					}
			}
			else if (armored)
				armored = false;
			else if (!damaged)
			damaged = true;
		}
		Player * player = const_cast<Player *>(o);
		SGD::Vector Bounce = player->GetRect().ComputeCenter() - this->GetRect().ComputeCenter();
		Bounce.Normalize();
		player->SetVelocity(Bounce * 100);
		player->SetDestinationPlanet(nullptr);
		player->SetCurrentPlanet(nullptr);
		player->SetGrappleActive(false);

	}
}

/*BossPlanets Methods*/
BossPlanets::BossPlanets()
{
	SGD::GraphicsManager::GetInstance()->UnloadTexture(image);
	image = SGD::GraphicsManager::GetInstance()->LoadTexture("resources/images/boss/Boss Planet.png", {255,255,255,255});
}

BossPlanets::~BossPlanets()
{
	SGD::GraphicsManager::GetInstance()->UnloadTexture(image);
	SetOwner(nullptr);
}

void BossPlanets::SetOwner(Zone* o)
{
	if (nullptr != owner)
		owner->Release();

	owner = o;

	if (nullptr != owner)
		owner->AddRef();
}

void BossPlanets::Render()
{
	SGD::Rectangle camOffset{ { Game::GetInstance()->GetCameraPos().x - 200,
		Game::GetInstance()->GetCameraPos().y - 200 },
		SGD::Size{ (Game::GetInstance()->GetScreenWidth() + 1000) / Game::GetInstance()->GetZoomLevel(),
		(Game::GetInstance()->GetScreenHeight() + 1000) / Game::GetInstance()->GetZoomLevel() } };
	SGD::Rectangle posRect = { this->GetRect().ComputeCenter(), SGD::Size{ 1, 1 } };
	if (camOffset.IsIntersecting(posRect))
	{
		collisionFlag = 0;
		SGD::GraphicsManager* graphics = SGD::GraphicsManager::GetInstance();
		SGD::Rectangle rect = { SGD::Point{ position.x - Game::GetInstance()->GetCameraPos().x,
			position.y - Game::GetInstance()->GetCameraPos().y }, size };

		SGD::Rectangle renderRect{36, 38, 220, 221};

		SGD::Point renderPos{ (position.x - Game::GetInstance()->GetCameraPos().x) * Game::GetInstance()->GetZoomLevel(),
			(position.y - Game::GetInstance()->GetCameraPos().y) * Game::GetInstance()->GetZoomLevel() };

		graphics->DrawTextureSection(image, renderPos, renderRect, 0.0f, {}, {},
			(SGD::Size{ Game::GetInstance()->GetZoomLevel() * 2.f, Game::GetInstance()->GetZoomLevel() * 2.f }));
	}
	else
		collisionFlag = -1;
}

void BossPlanets::Update(float elapsedTime)
{
	int checkDead = 0;
	for (unsigned int i = 0; i < weakPoints.size(); i++)
	{
		if (weakPoints[i]->GetDamaged())
			checkDead++;
		if (4 == checkDead)
			alive = false;
	}
}
void BossPlanets::SetWeakPoint(WeakPoint*helper)
{
	weakPoints.push_back(helper);
}
void BossPlanets::SetWeakPoints()
{
	SGD::Vector v1 = { -1, -1 };
	v1 *= this->GetRadius();
	SGD::Point wp1Pos = this->GetRect().ComputeCenter();
	wp1Pos.x += v1.x + 75;
	wp1Pos.y += v1.y;
	WeakPoint* wp1 = new WeakPoint(this);
	wp1->SetPosition(wp1Pos);
	wp1->SetSize({ 50, 50 });
	wp1->CalculateRadius();
	weakPoints.push_back(wp1);

	SGD::Vector v2 = { 1, -1 };
	v2 *= this->GetRadius();
	SGD::Point wp2Pos = this->GetRect().ComputeCenter();
	wp2Pos.x += v2.x - 100;
	wp2Pos.y += v2.y;
	WeakPoint* wp2 = new WeakPoint(this);
	wp2->SetPosition(wp2Pos);
	wp2->SetSize({ 50, 50 });
	wp2->CalculateRadius();
	weakPoints.push_back(wp2);

	SGD::Vector v3 = { 1, 1 };
	v3 *= this->GetRadius();
	SGD::Point wp3Pos = this->GetRect().ComputeCenter();
	wp3Pos.x += v3.x - 50;
	wp3Pos.y += v3.y - 100;
	WeakPoint* wp3 = new WeakPoint(this);
	wp3->SetPosition(wp3Pos);
	wp3->SetSize({ 50, 50 });
	wp3->CalculateRadius();
	weakPoints.push_back(wp3);

	SGD::Vector v4 = { -1, 1 };
	v4 *= this->GetRadius();
	SGD::Point wp4Pos = this->GetRect().ComputeCenter();
	wp4Pos.x += v4.x;
	wp4Pos.y += v4.y - 100;
	WeakPoint* wp4 = new WeakPoint(this);
	wp4->SetPosition(wp4Pos);
	wp4->SetSize({ 50, 50 });
	wp4->CalculateRadius();
	weakPoints.push_back(wp4);

	for (unsigned int i = 0; i < weakPoints.size(); i++)
	{
		if (owner->GetZoneType() == Zone::ZONE2)
			weakPoints[i]->SetArmored(true);
		else if (owner->GetZoneType() == Zone::ZONE3)
		{
			weakPoints[i]->SetArmored(true);
			weakPoints[i]->SetSpiked(true);
		}
		else if (owner->GetZoneType() == Zone::ZONE4)
		{
			weakPoints[i]->SetArmored(true);
			weakPoints[i]->SetSpiked(true);
			weakPoints[i]->SetTentacles(true);
		}
		else if (owner->GetZoneType() == Zone::ZONE5)
		{
			weakPoints[i]->SetArmored(true);
			weakPoints[i]->SetSpiked(true);
			weakPoints[i]->SetTentacles(true);
			weakPoints[i]->SetMancerSpawn(true);
		}
	}
}